/*
	@file: log/source/Log.cpp
	@author: Wolfhead
 */
#include "Log.h"
#include <stdarg.h>
#include <boost/thread/tss.hpp>
#include "detail/Singleton.h"
#include "LogData.h"

namespace logger
{

// refactor later
namespace _detail_ 
{
	struct Buffer
	{
		enum 
		{
			kBufferSize = 40960 // 40k  
		};
		char buffer[kBufferSize];
	};
}

static boost::thread_specific_ptr<_detail_::Buffer> g_buffer_ptr;

void logf(LogPriority priority,		  
		  const LogContext& context,
	      const char * format, ...)
{
	if (!(get_log_dispatcher().get_priority() & priority))
	{
		return;
	}

	if (!g_buffer_ptr.get())
	{
		g_buffer_ptr.reset(new _detail_::Buffer);
	}
	va_list ap;
	va_start(ap, format);
	int ret = vsnprintf(g_buffer_ptr->buffer, _detail_::Buffer::kBufferSize, format, ap);
	va_end(ap);
	if (ret < 0)
	{
		return;
	}
	else
	{
		LogDataPtr data_ptr(
			new LogData(
				priority, 
				context, 
				std::string(g_buffer_ptr->buffer, ret)));

		get_log_dispatcher().log(data_ptr);
		return;
	}
}

void logf(const std::string& name, 
	      const LogContext& context,
	      const char * format, ...)
{

	if (!g_buffer_ptr.get())
	{
		g_buffer_ptr.reset(new _detail_::Buffer);
	}

	va_list ap;
	va_start(ap, format);
	int ret = vsnprintf(g_buffer_ptr->buffer, _detail_::Buffer::kBufferSize, format, ap);
	va_end(ap);
	if (ret < 0)
	{
		return;
	}
	else
	{
		LogDataPtr data_ptr(
			new LogData(
				name, 
				context, 
				std::string(g_buffer_ptr->buffer, ret)));

		get_log_dispatcher().log(data_ptr);
		return;
	}
}


}//namespace logger
